// -*-mode:c++; coding:utf-8-*-

#include <sstream>

#include <xbase_utility.hpp>

#include "imphub_dbp_protocol.hpp"

template<typename T>
		inline
		std::string to_string(const T &obj) {
			return obj.to_string();
		}

		template<>
		inline
		std::string to_string(const std::string &str) {
			return str;
		}

#define integer_to_string(type)				\
		template<>				\
		inline					\
		std::string to_string(const type &n) {	\
			std::ostringstream out;		\
			out << n;			\
			return out.str();		\
		}

		integer_to_string(uint32_t)

#undef integer_to_string

template<typename elemT,
	 typename charT, typename traits>
static inline
std::basic_ostream<charT, traits> &
operator<<(std::basic_ostream<charT, traits> &out,
	   const std::vector<elemT> &vec)
{
	typedef typename std::vector<elemT>::const_iterator cit_type;
	out << "[";
	const cit_type end = vec.end();
	cit_type it = vec.begin();
	if(it != end)
	{
		out << to_string(*it);
		for(++it; it != end; ++it)
		{
			out << ", " << to_string(*it);
		}
	}
	out << "]";
	return out;
}

std::string packet::to_string() const {
	std::ostringstream out;
	out << "{version: " << m_version
	    << "; sign: " << m_sign
	    << "; seq: " << m_seq
	    << "; flag: " << m_flag
	    << "; length: " << m_length
	    << "; reserve: 16 bytes"
	    << "; type: " << m_type
	    << "(" << type_name(type_code())
	    << ")}";
	return out.str();
}

std::string insert_request::to_string() const {
	std::ostringstream out;
	out << "{cid: " << dump_string_hex(m_cid)
	    << "; gcid: " << dump_string_hex(m_gcid)
	    << "; filesize: " << m_filesize
	    << "; peerid_list: " << m_peerid_list
	    << "}";
	return out.str();
}

std::string query_request::to_string() const {
	std::ostringstream out;
	out << "{cid: " << m_cid
	    << "; limit_offset: " << m_limit_offset
	    << "; limit_count: " << m_limit_count
	    << "}";
	return out.str();
}

std::string peer_id::to_string() const {
	std::ostringstream out;
	out << "{cid: " << dump_string_hex(m_cid)
	    << "; gcid: " << dump_string_hex(m_gcid)
	    << "; filesize: " << m_filesize
	    << "; peerid: " << m_peerid
	    << "}";
	return out.str();
}

std::string query_response::to_string() const {
	std::ostringstream out;
	out << "{result: " << m_result
	    << "; peerid_list: " << m_peerid_list
	    << "}";
	return out.str();
}
